package bingo.component.amchart.graphics;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import net.bingosoft.common.BeanHelper;
import net.bingosoft.common.util.ClassUtil;
import net.bingosoft.common.util.XMLUtil;

import org.dom4j.Element;
import org.dom4j.Node;

/**
 * Jun 24, 2008 4:35:22 PM
 * Author:yangdongyu(yangdy@bingosoft.net)
 * ReadMe:
 * ChangeLog:
 */
public abstract class BaseGraphic implements Graphic{

	/**
	 * 将该图代表的对象转换成xml
	 */
	public Node toXML() {
		Class<?> clazz = this.getClass();
		Element root = XMLUtil.createElement(getAlias());
		Field[] fields = clazz.getDeclaredFields();
		String textPropertyName = getTextPropertyName();
		List<String> subElementProperties = getSubElementProperties();
		for(Field field : fields){
			String fieldName = field.getName();
			Object fieldvalue = null;
			try {
				fieldvalue = BeanHelper.getRawProperty(this, fieldName);
			} catch (IllegalArgumentException e) {
				throw e;
			} catch (Exception e) {
				throw new RuntimeException("读取对象属性时发生错误，请检查...",e);
			}
			if(fieldvalue != null){
				if(ClassUtil.isPrimitiveOrWrapper(fieldvalue.getClass()) || fieldvalue instanceof String){
					if(fieldName.equals(textPropertyName)){
						root.addText(fieldvalue.toString());
					}else if(subElementProperties.contains(fieldName)){
						Element e = XMLUtil.createElement(fieldName);
						e.addText(fieldvalue.toString());
						root.add(e);
					}else{
						root.addAttribute(fieldName, fieldvalue.toString());
					}
				}else if(fieldvalue instanceof Collection){
					Iterator<?> it = ((Collection<?>)fieldvalue).iterator();
					while(it.hasNext()){
						Object child = it.next();
						if(child instanceof Graphic){
							root.add(((Graphic)child).toXML());
						}

					}
				}else if(fieldvalue instanceof BaseGraphic){
					root.add(((BaseGraphic)fieldvalue).toXML());
				}
			}

		}
		if(this.isRootElement()){
			return XMLUtil.createDocument(root);
		}
		return root;
	}
	/**
	 * 获取生成xml时用来填充元素包含的text的属性名称
	 * @return
	 */
	protected String getTextPropertyName(){
		return "";
	}
	/**
	 * 获取作为子元素的属性列表
	 * @return
	 */
	protected List<String> getSubElementProperties(){
		return Collections.emptyList();
	}

	/**
	 * 获取生成xml忽略的属性
	 * @return
	 */
	protected List<String> getIgnoredProperties(){
		return Collections.emptyList();
	}

    protected String getAlias() {
    	return this.getClass().getSimpleName().toLowerCase();
    }
}
